package com.github.andy0106.kersstjtl.api;

import com.github.andy0106.kersstjtl.files.File;
import com.google.gson.Gson;

import java.io.IOException;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

class ApiRequest extends HttpUtils {
    public static String API_ADDRESS = "http://kersst.api:8000/";
    public static final String API_VERSION = "v1";
    public static final Gson gson = new Gson();

    public static void setApiAddress(String ip, String port) {
        API_ADDRESS = "http://" + ip + ":" + port + "/";
    }

    public static long getTimestamp() {
        try {
            String response = new String(get(API_ADDRESS + "timestamp"));
            return gson.fromJson(response, Timestamp.class).getTimestamp();
        } catch (IOException e) {
            e.printStackTrace();
            return 0L;
        }
    }

    public static String getUrl(String ROUTE, String METHOD, Map<String, String> query) {
        StringBuilder s = new StringBuilder(API_ADDRESS + API_VERSION + '/' + ROUTE + '/' + METHOD);

        if (query == null) {
            return s.toString();
        }

        s.append("?");
        for (String k : query.keySet()) {
            String v = query.get(k);
            if (v.equals("")) continue;
            s.append(k).append("=").append(v).append("&");
        }
        return s.toString();
    }

    public static ArrayList<Package> get_all_packages() {
        ArrayList<Package> packages = new ArrayList<>();
        try {
            String response = new String(get(getUrl(ApiRoutes.PACKAGES, ApiMethods.GETALL, null)));
            packages = gson.fromJson(response, PackagesResponse.class).getData();
            return packages;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static ArrayList<String> get_all_packages_name() {
        ArrayList<String> packages = new ArrayList<>();
        try {
            String response = new String(get(getUrl(ApiRoutes.PACKAGES, ApiMethods.GETALL_NAME, null)));
            packages = gson.fromJson(response, ListStringResponse.class).getData();
            return packages;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static ArrayList<Package> get_packages(String packname, String packver, String gamever) {
        ArrayList<Package> packages = new ArrayList<>();
        HashMap<String, String> query = new HashMap<>();
        query.put("packname", packname);
        query.put("packver", packver);
        query.put("gamever", gamever);
        try {
            String response = new String(get(getUrl(ApiRoutes.PACKAGES, ApiMethods.GET, query)));
            packages = gson.fromJson(response, PackagesResponse.class).getData();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return packages;
    }

    public static ArrayList<Mod> get_mods(String modname, String modver, String gamever) {
        ArrayList<Mod> mods = new ArrayList<>();
        HashMap<String, String> query = new HashMap<>();
        query.put("modname", modname);
        query.put("modver", modver);
        query.put("gamever", gamever);
        try {
            String response = new String(get(getUrl(ApiRoutes.MODS, ApiMethods.GET, query)));
            mods = gson.fromJson(response, ModsResponse.class).getData();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return mods;
    }

    public static boolean download_file(String packname, String filename, String outpath) {
        return download(API_ADDRESS + "serveroot/packages/" + packname + "/files/", filename, outpath);
    }

    public static Package get_package_config(Package pack) {
        try {
            String response = new String(get(API_ADDRESS + "serveroot/packages/" + pack.getName() + "/" + pack.getFilename()));
            return gson.fromJson(response, Package.class);
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

    public static boolean download(String targetpath, String filename, String outpath) {
        try {
            byte[] context = get(targetpath + filename);
            File outfile = new File(filename, outpath);
            if (!outfile.isExists())
                Files.createFile(outfile.getPaths());
            outfile.write(context);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }

    public static boolean download_mod(Mod mod, String mods_dir) {
        return download(API_ADDRESS + "serveroot/mods/" + mod.getName() + "/", mod.getFilename(), mods_dir);
    }

    public static boolean download_messmod(String name, String mods_dir) {
        return download(API_ADDRESS + "serveroot/mess_mods/", name, mods_dir);
    }
}

class ApiRoutes {
    public static final String MODS = "mods";
    public static final String PACKAGES = "packages";
}
class ApiMethods {
    public static final String GET = "get";
    public static final String GETALL = "getall";
    public static final String GETALL_NAME = "getall_name";
}
class PackagesResponse extends JsonResponse<ArrayList<Package>> {}
class ModsResponse extends JsonResponse<ArrayList<Mod>> {}
class ListStringResponse extends JsonResponse<ArrayList<String>> {}
class Timestamp {
    private Long timestamp;

    public Long getTimestamp() {
        return timestamp;
    }

    public void setTimestamp(Long timestamp) {
        this.timestamp = timestamp;
    }
}